<?php

class CommandStmt implements ExecutableStmt
{
	private $name;
	private $call;
	private $args;

	public function __construct ($name, $args, $mode)
	{
		$call = $mode->getCall($name, CliMode::ID_COMMAND);

		$this->name = $name;
		$this->call = $call;
		$this->args = $args;
	}

	public function execute (CliContext $context)
	{
		$args = new ArgContext($context, $this->args);
		$result = CliLib::doCall($this->name, $this->call, $args);
		$result = CliLib::valueOf($result, $context);

		if ($result instanceof ExpNumber)
		{
			$result = $result->toNumber();
		}

		return $result;
	}

	public function __toString ()
	{
		$string = CliParser::getDefaultCommandChar();
		$string .= $this->name;

		// Put the command call here, so we can implode cleanly
		$args = array($string);

		foreach ($this->args as $arg)
		{
			// If the argument is a expression, output it as such
			if ($arg instanceof ExpressionStmt)
			{
				$args[] = "\{$arg}";
			}
			// If it's something fancy like number, stringify it
			elseif (!is_string($arg))
			{
				$args[] = (string) $arg;
			}
			else
			{
				// If the string is literal, just output it as such
				if (preg_match('/^[^+\-.\d\s\'"][^\s\'"]*$/', $arg))
				{
					$args[] = $arg;
				}
				else
				{
					// Quote all backslashes
					$arg = str_replace('\\', '\\\\', $arg);

					// If string has only ' or ", surround with lacking one
					if (!preg_match('/^(?:([^\']+)|([^"]+))$/', $arg))
					{
						$args[] = isset($match[2]) ? "\"$arg\"" : "'$arg'";
					}
					// Surround with " escaping all existing ones
					else
					{
						$args[] = '"' . str_replace('"', '\\"', $arg) . '"';
					}
				}
			}
		}

		return implode(' ', $args);
	}

}

?>